﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LazyKex.Semantic;

namespace LazyKex.Syntatic
{
    public class ExpressionSubMachine
    {

        private LazyKDislexic dislexic;
        
        private SemanticLazyKex semantic;

        private int state = 0;


        public ExpressionSubMachine(LazyKDislexic dislexic, SemanticLazyKex semantic)
        {
            this.dislexic = dislexic;
            this.semantic = semantic;
        }

        public bool Process()
        {
            bool consume = true;
            while (consume)
            {
                switch (state)
                {
                    case 0:
                        consume = State0();
                        break;
                    case 1:
                        // estado 1 não consome mais nada e retorna
                        consume = false;
                        break;
                    case 2:
                        consume = State2();
                        break;
                    case 3:
                        consume = State3();
                        break;
                    case 4:
                        consume = State4();
                        break;
                    case 5:
                        consume = State5();
                        break;
                }
            }
            return AcceptationState();
        }

       

        private bool AcceptationState()
        {
            semantic.EndExpression();
            return state == 1 || state == 2;
        }

        private bool State0()
        {
            char c = dislexic.CurrentToken();
            switch (c)
            {
                case 'S':
                case 's':
                case 'I':
                case 'K':
                case 'k':
                    semantic.NormalCharacterAction(c);
                    state = 1;
                    break;
                case 'i':
                    semantic.iCharacterAction();
                    state = 1;
                    break;
                case '0':
                case '1':
                    semantic.NormalCharacterAction(c);
                    state = 2;
                    break;
                case '*':
                case '`':
                    semantic.Q3Action(c);
                    state = 3;
                    break;
                case '(':
                    semantic.NewScope();
                    state = 4;
                    break;
                default:
                    return false;
            }
            return true;
        }

        private bool State2()
        {
            if (dislexic.HasMoreTokens())
            {
                dislexic.NextToken();
                char c = dislexic.CurrentToken();

                switch (c)
                {
                    case '0':
                    case '1':
                        semantic.NormalCharacterAction(c);
                        state = 2;
                        break;
                    default:
                        return false;
                }
            }

            return false;
        }

        private bool State3()
        {
            if (dislexic.HasMoreTokens())
            {
                dislexic.NextToken();
                ExpressionSubMachine subMachine = new ExpressionSubMachine(dislexic, semantic);
                if (subMachine.Process())
                {

                    state = 5;
                    return true;
                }
            }
            return false;
        }

        private bool State4()
        {
            if (dislexic.HasMoreTokens())
            {
                dislexic.NextToken();
                char c = dislexic.CurrentToken();
                switch (c)
                {
                    case ')':
                        semantic.EndScope();
                        state = 1;
                        return true;
                        break;
                    default:

                        ExpressionSubMachine subMachine = new ExpressionSubMachine(dislexic, semantic);
                        if (subMachine.Process())
                        {
                            state = 4;
                            return true;
                        }
                        break;

                }
            }
        
            return false;
        }

        private bool State5()
        {
            if (dislexic.HasMoreTokens())
            {
                dislexic.NextToken();
                ExpressionSubMachine subMachine = new ExpressionSubMachine(dislexic, semantic);
                if (subMachine.Process())
                {

                    state = 1;
                    return true;
                }
            }
            return false;
        }

        

        

        

    }
}
